#ifndef __GAME_OBJECT_H__
#define __GAME_OBJECT_H__
#include "cocos2d.h"
USING_NS_CC;
#include "../include/IGameScene.h"
#include "../include/IGameLogic.h"
#include "../config/FishConfig.h"
#include "../config/GameConfig.h"
#include "../config/BulletConfig.h"
namespace fishingjoy
{
	namespace logic
	{
		enum EFishObjectState
		{
			EGOS_IDLE,
			EGOS_MOVE,
			EGOS_ROTATE,
			EGOS_DIE,
		};
		class CFishObject
		{
			scene::ISceneObject* m_pSceneObject;
			const config::SFishData* m_pFishData;
			EFishObjectState m_eGameObjectState;
			IGameLogic* m_pGameLogic;
			float m_TargetX;
			float m_TargetY;

			float m_CurrentX;
			float m_CurrentY;
			bool m_bNeedDestroyed;
			bool m_bMoveToAndStop;
			bool m_bMoveToAndDestroy;
			float m_Time;
			int m_iHp;
		public:
			CFishObject(scene::ISceneObject* pObj,const config::SFishData* pData,IGameLogic*  pLogic)
				:m_pSceneObject(pObj)
				,m_pFishData(pData)
				,m_eGameObjectState(EGOS_MOVE)
				,m_bMoveToAndStop(false)
				,m_bMoveToAndDestroy(false)
				,m_bNeedDestroyed(false)
				,m_pGameLogic(pLogic)
			{
				m_iHp = pData->HP;
			}
		public:
			void update(float dt)
			{
				switch(m_eGameObjectState)
				{
				case EGOS_MOVE:
					updateMove(dt);
					break;
				case EGOS_ROTATE:
					break;
				case EGOS_DIE:
					{
						m_Time += dt;
						if(m_Time > 3){
							m_bNeedDestroyed = true;
						}
					}
					break;
				case EGOS_IDLE:
					break;
				default:
					break;
				}
			}

			scene::ISceneObject* getSceneObj(){ return m_pSceneObject;}

			bool needDestroyed(){ return m_bNeedDestroyed; }

			void setPosition(int x,int y)
			{
				m_CurrentX = x;
				m_CurrentY = y;
				m_pSceneObject->setPosition(x,y);
			}

			float getPosX(){ return m_CurrentX; }
			float getPosY(){ return m_CurrentY; }

			void randomTarget()
			{
				m_TargetX = CCRANDOM_0_1()*(config::CGameConfig::getExtendSize()+480);
				m_TargetY = CCRANDOM_0_1()*(config::CGameConfig::getExtendSize()+320);
				setTarget(m_TargetX,m_TargetY);
				m_eGameObjectState = EGOS_MOVE;
			}

			void moveToAndStop(int x,int y)
			{
				setTarget(x,y);
				m_bMoveToAndStop = true;
				m_eGameObjectState = EGOS_MOVE;
			}

			void moveToAndDestroy(int x,int y)
			{
				setTarget(x,y);
				m_eGameObjectState = EGOS_MOVE;
				m_bMoveToAndDestroy = true;
			}

			void moveTo(int x, int y)
			{
				m_bMoveToAndStop = false;
				setTarget(x,y);
				m_eGameObjectState = EGOS_MOVE;
			}

			void setDuration(int degree)
			{
				m_pSceneObject->setDuration(180-degree);
			}

			void onHit(int atk);

			bool isDead(){ return m_eGameObjectState == EGOS_DIE; }

		private:
			void setTarget(int x,int y)
			{
				m_TargetX = x;
				m_TargetY = y;
				float dx = m_TargetX - m_CurrentX;
				float dy = m_TargetY - m_CurrentY;
				float angle = atan(dy/dx);
				float degree = angle*180/3.1415926;
				if(dx<0){
					degree += 180;
				}
				setDuration(degree);
			}
			void updateMove(float dt);
		};

		enum EBulletObjectState
		{
			EBOS_NORMAL,
			EBOS_EXPLODE,
		};
		class CBulletObject
		{
			enum{
				EXPLODE_TIME = 1,
			};
			scene::ISceneObject* m_pSceneObject;
			EBulletObjectState m_eButtletObjectState;
			IGameLogic* m_pGameLogic;
			float m_OrgX;
			float m_OrgY;
			float m_CurrentX;
			float m_CurrentY;
			float m_Dir;
			float m_Time;
			bool m_bNeedDestroyed;

			float m_Speed;
			float m_Distance;
			int m_iAtk;
		public:
			CBulletObject(scene::ISceneObject* pObj,IGameLogic* pLogic,int level)
				:m_pSceneObject(pObj)
				,m_pGameLogic(pLogic)
				,m_eButtletObjectState(EBOS_NORMAL)
				,m_Time(0)
				,m_bNeedDestroyed(false)
			{
				const config::SBulletData* pData = config::CBulletConfig::getData(level);
				if(pData==NULL){
					m_Speed = 0;
					m_Distance = 0;
					m_iAtk = 0;
				}
				else{
					m_Speed = pData->Speed;
					m_Distance = pData->Distance;
					m_iAtk = pData->Atk;
				}
				
				char buf[32];
				sprintf(buf,"bullet%d",level);
				pObj->setAnimation(buf);
			}
			scene::ISceneObject* getSceneObj(){ return m_pSceneObject;}

			bool needDestroyed(){ return m_bNeedDestroyed; }
			void setPosition(float x,float y)
			{
				m_OrgX = x;
				m_OrgY = y;
				m_CurrentX = x;
				m_CurrentY = y;
				m_pSceneObject->setPosition(x,y);
			}

			void setDuration(int degree)
			{
				m_Dir = degree;
				m_pSceneObject->setDuration(degree);
			}
			void update(float dt);

		private:
			bool isRectCollision (CCRect rect1, CCRect rect2);
			void updateNormal(float dt);
		};
	}
}
#endif